package com.gitee.cui.concurrency.lockfree;

import com.gitee.cui.util.Print;
import com.gitee.cui.util.ThreadUtil;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 写时复制测试类
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021/12/1 15:38
 **/
public class CopyOnWriteArrayListTest {

    public static class ConcurrentTarget implements Runnable {

        private List<String> targetList = null;

        public ConcurrentTarget(List<String> targetList) {
            this.targetList = targetList;
        }

        @Override
        public void run() {
            Iterator<String> iterator = targetList.iterator();
            while (iterator.hasNext()) {
                String threadName = Thread.currentThread().getName();
                Print.tco("开始往同比队列中加入线程名称：" + threadName);
                targetList.add(threadName);
            }
        }
    }

    /**
     * 通过collections提供的静态同步容器方法，在迭代时进行列表的修改，会报错
     */
    @Test
    public void synchronizedListTest() {
        List<String> notSafeList = Arrays.asList("a", "b", "c");
        List<String> syncList = Collections.synchronizedList(notSafeList);

        ConcurrentTarget target = new ConcurrentTarget(syncList);

        for (int i = 0; i < 10; i++) {
            new Thread(target, "线程" + i).start();
        }
        ThreadUtil.sleepSeconds(1000);
    }

    /**
     * 使用CopyOnWriteArrayList构建的写时复制类进行测试，不会出线遍历时修改列表内容报错问题
     */
    @Test
    public void copyOnWriteArrayListTest() {
        List<String> notSafeList = Arrays.asList("a", "b", "c");
        CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>(notSafeList);

        ConcurrentTarget target = new ConcurrentTarget(copyOnWriteArrayList);
        for (int i = 0; i < 10; i++) {
            new Thread(target, "线程" + i).start();
        }
        ThreadUtil.sleepSeconds(1000);
    }
}
